package Controllers;

import domain.User;
import domain.UserRole;
import exceptions.GeneralServiceException;
import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import service.impl.UserServiceImpl;

/*
 * @author yuyok
 */
@ManagedBean(name = "user")
@RequestScoped
public class UserManagerController {

    @EJB
    private UserServiceImpl usersService;
    @Size(min = 4,
    message = "at least 4 symbols")
    private String login;
    @Size(min = 4,
    message = "at least 4 symbols")
    private String password;
    private String firstName;
    private String lastName;
    @Pattern(regexp = "[a-zA-Z0-9]+@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+",
    message = "Email format is invalid.")
    private String email;
    private Date birthDate;
    private User user;
    @ManagedProperty("#{param.id}")
    private String id;
    @Size(min = 4,
    message = "at least 4 symbols")
    private String oldPasswd;
    @Size(min = 4,
    message = "at least 4 symbols")
    private String newPasswd;
    @Size(min = 4,
    message = "at least 4 symbols")
    private String renewPasswd;

    public String getNewPasswd() {
        return newPasswd;
    }

    public void setNewPasswd(String newPasswd) {
        this.newPasswd = newPasswd;
    }

    public String getOldPasswd() {
        return oldPasswd;
    }

    public void setOldPasswd(String oldPasswd) {
        this.oldPasswd = oldPasswd;
    }

    public String getRenewPasswd() {
        return renewPasswd;
    }

    public void setRenewPasswd(String renewPasswd) {
        this.renewPasswd = renewPasswd;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Date getBirthDate() {
        Date result;
        if (getUserLogin() != null) {
            result = usersService.getUserByLogin(getUserLogin()).getBirthDate();
        } else {
            result = null;
        }
        return result;
    }

    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }

    public String getEmail() {
        String result;
        if (getUserLogin() != null) {
            result = usersService.getUserByLogin(getUserLogin()).getEmail();
        } else {
            result = null;
        }
        return result;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getFirstName() {
        String result;
        if (getUserLogin() != null) {
            result = usersService.getUserByLogin(getUserLogin()).getFirstName();
        } else {
            result = null;
        }
        return result;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        String result;
        if (getUserLogin() != null) {
            result = usersService.getUserByLogin(getUserLogin()).getLastName();
        } else {
            result = null;
        }
        return result;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getLogin() {
        return getUserLogin();
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public String getPassword() {
        String result;
        if (getUserLogin() != null) {
            result = usersService.getUserByLogin(getUserLogin()).getPassword();
        } else {
            result = null;
        }
        return result;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    /*
     * Creates a new instance of UserManagerController 
     */
    public UserManagerController() {
    }

    public String login() {
        String result;
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
        try {
            request.login(login, password);
            result = "index";
        } catch (ServletException ex) {
            Logger.getLogger(UserManagerController.class.getName()).log(Level.SEVERE, null, ex);
            FacesContext.getCurrentInstance().addMessage("loginForm", new FacesMessage(
                    FacesMessage.SEVERITY_ERROR, "Login failed!", null));
            result = "login";
        }
        return result;
    }

    public String logout() {
        String result;
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
        try {
            request.logout();
            result = "index";
        } catch (ServletException ex) {
            Logger.getLogger(UserManagerController.class.getName()).log(Level.SEVERE, null, ex);
            result = "error";
        }
        return result;
    }

    public Integer isAuthenticated() {
        FacesContext context = FacesContext.getCurrentInstance();
        if (context.getExternalContext().getUserPrincipal() == null) {
            return 0;
        }
        return 1;
    }

    public boolean isUserAdmin() {
        FacesContext context = FacesContext.getCurrentInstance();
        return context.getExternalContext().isUserInRole("ADMIN");
    }

    public boolean isSimpleUser() {
        FacesContext context = FacesContext.getCurrentInstance();
        return context.getExternalContext().isUserInRole("USER");
    }

    public String getUserLogin() {
        Principal principal = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
        if (principal != null) {
            return principal.getName();
        }
        return null;
    }

    public String gotoLogin() {
        return "login";
    }

    public String gotoRegister() {
        return "register";
    }

    public String register() {
        User u = new User();
        u.setEmail(email);
        u.setLogin(login);
        u.setFirstName(firstName);
        u.setLastName(lastName);
        u.setIsEnable(true);
        u.setPassword(password);
        u.setAccountInfo(null);
        u.setBirthDate(birthDate);
        
        try {
            usersService.register(u);
            FacesContext.getCurrentInstance().addMessage("registerForm", new FacesMessage(
                    FacesMessage.SEVERITY_INFO, "Registration succesful", null));
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(UserManagerController.class.getName()).log(Level.SEVERE, null, ex);
            FacesContext.getCurrentInstance().addMessage("registerForm", new FacesMessage(
                    FacesMessage.SEVERITY_ERROR, "Registration failed!", null));
        } catch (GeneralServiceException ex) {
            Logger.getLogger(UserManagerController.class.getName()).log(Level.SEVERE, null, ex);
            FacesContext.getCurrentInstance().addMessage("registerForm", new FacesMessage(
                    FacesMessage.SEVERITY_ERROR, "Registration failed!", null));
        }
        return "register";
    }

    public List<User> getAllUsers() {
        return usersService.getUsersByRole(UserRole.USER);
    }

    public void deleteUser() {
        Long userId = new Long(id);
        usersService.delEntityById(userId);
    }

    public User getUserInfo() {
        return usersService.getUserByLogin(getUserLogin());
    }

    public String updateInfo() {
        User u = usersService.getUserByLogin(getUserLogin());
        u.setFirstName(firstName);
        u.setLastName(lastName);
        u.setBirthDate(birthDate);
        try {
            usersService.save(u);
            FacesContext.getCurrentInstance().addMessage("updateInfo", new FacesMessage(
                    FacesMessage.SEVERITY_INFO, "Informtion updated succesfully!", null));
        } catch (GeneralServiceException ex) {
            Logger.getLogger(UserManagerController.class.getName()).log(Level.SEVERE, null, ex);
            FacesContext.getCurrentInstance().addMessage("updateInfo", new FacesMessage(
                    FacesMessage.SEVERITY_ERROR, "Informtion update failed!", null));
        }

//        FacesContext context = FacesContext.getCurrentInstance();
//        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
//        try {
//            request.logout();
//        } catch (ServletException ex) {
//            Logger.getLogger(UserManagerController.class.getName()).log(Level.SEVERE, null, ex);
//            result = "error";
//        }
        return "profile";
    }

    public String changePassword() throws UnsupportedEncodingException, IllegalArgumentException, GeneralServiceException {
        if (getPassword().equals(usersService.md5(oldPasswd))) {
            if (!newPasswd.equals(renewPasswd)) {
                FacesContext.getCurrentInstance().addMessage("changePasswd", new FacesMessage(
                        FacesMessage.SEVERITY_ERROR, "Retype new password!", null));
            } else {
                User u = usersService.getUserByLogin(getUserLogin());
                u.setPassword(newPasswd);
                usersService.register(u);
                FacesContext.getCurrentInstance().addMessage("changePasswd", new FacesMessage(
                        FacesMessage.SEVERITY_INFO, "Password succesfully changed!", null));
            }
        } else {
            FacesContext.getCurrentInstance().addMessage("changePasswd", new FacesMessage(
                    FacesMessage.SEVERITY_ERROR, "Check old password!", null));
        }
        return "changepasswd";
    }
}
